// ---------------------------------- 扩展Window对象

/**
 * 模拟java.text.SimpleDateFormat的parse方法
 * 可以分别转换日期和时间，转换时间时，默认日期为1970年1月1日。
 * 使用限制，每个有独立意义数值之间必须使用分隔符，如下例中使用的横线与空格。
 * 格式示例，yyyy-MM-dd HH:mm:ss，或yyyy-M-d H:m:s
 * 值示例，2010-02-07 13:00:05，或2010-12-3 15:5:24
 * @param {String} value	转换值
 * @param {String} format	转换格式
 * @return {Date} 	返回Date对象
 */
window.parseDate = function(value, format) {
	var placeHolders = ['d', 'y', 'M', 'H', 'm', 's'];
	var formatRp = format;
	var placesHoldersPos = []; 
	for (var i = 0; i < placeHolders.length; i++) {
		var regex = void(0);
		switch (placeHolders[i]) {
		case 'y':
			regex = /y{4}/;
			break;
		case 'M':
			regex = /M{1,2}/;
			break;
		case 'd':
			regex = /d{1,2}/;
			break;
		case 'H':
			regex = /H{1,2}/;
			break;
		case 'm':
			regex = /m{1,2}/;
			break;
		case 's':
			regex = /s{1,2}/;
			break;
		}
		
		var matchs = format.match(regex);
		if (matchs) {
			var index = format.indexOf(matchs[0]);
			if (index != -1) {
				placesHoldersPos.push({
					holder : placeHolders[i],
					index : index
				});
				if (placeHolders[i] == 'y')
					formatRp = formatRp.replace(matchs, "(\\d{4})");
				else
					formatRp = formatRp.replace(matchs, "(\\d{1,2})");
			}
		}
	}
	
	var datePattern = new RegExp('^' + formatRp + '$');
	if (!datePattern.test(value)) {
		throw new Error('window.parseDate Error: the value was not match the given format.');
	}
	
	placesHoldersPos.sort(function (item1, item2) {
		return item1.index - item2.index;
	});
	
	var valueSlices = datePattern.exec(value);
	
	var dateResult = new Date(1970,0,1,0,0,0);
	for (var i = 1; i < valueSlices.length; i++) {
		var item = placesHoldersPos[i - 1];
		var value2 = parseInt(valueSlices[i], 10);
		
		switch (item.holder) {
		case "y":
			dateResult.setFullYear(value2);
			break;
		case "M":
			dateResult.setMonth(value2 - 1);
			break;
		case "d":
			dateResult.setDate(value2);
			break;
		case "H":
			dateResult.setHours(value2);
			break;
		case "m":
			dateResult.setMinutes(value2);
			break;
		case "s":
			dateResult.setSeconds(value2);
			break;
		}
	}
	
	return dateResult;
}

// ------------------------------------------- 验证框架

//消息容器
var VALIDATION_MESSAGES = [];

var NOSELECT_VALUE = "com.ai.core.jsf.noselect";

function genONSUBMIT(formId, validationFormFuncName) {
	var oldSubmitFunc = document.getElementById(formId).onsubmit;
	return function () {
		if (!this._ajaxSingle && !!this._containerId) {
			if (!/_region$/.test(this._containerId)) {
				var container = document.getElementById(this._containerId);
				if (!container || !jQuery(container).hasClass('region') || !jQuery(container).hasClass('regionSubmit')) {
					return eval(validationFormFuncName + '()');
				}
			}
		} 
		if (oldSubmitFunc) 
			return oldSubmitFunc.apply(this);
		return true;
	}
}

/**
 * 单个输入项验证方法
 */
function validateInput(formId, name, functionMapper) {
	var value = "";
	var inputs = void(0);
	if (formId)
		inputs = jQuery('#' + formId + ' [name="' + name + '"]');
	else
		inputs = jQuery('[name="' + name + '"]');
	var tagName = "";
	if (inputs.size() > 0)
		tagName = inputs[0].tagName.toLowerCase();
	
	if (inputs.size() == 0) {
		return;
	} else if (inputs.size() == 1) {
		value = inputs.val();
	} else if (inputs.size() > 1) {
		if (tagName == "input") {
			var type = jQuery(inputs[0]).attr('type');
			if (type == 'checkbox' || type == 'radio') {
				inputs = jQuery('#' + formId + ' [name="' + name + '"]:checked');
			}
		}
		value = [];
		inputs.each(function () {
			value.push(jQuery(this).val());
		});
	}

	for (var i = 0; i < functionMapper.length; i++) {
		var funcName = functionMapper[i]['funcName'];
		if ((funcName == "isNotEmpty" || funcName == "isNotBlank") && tagName == "select" && value == NOSELECT_VALUE) {
			VALIDATION_MESSAGES.push(functionMapper[i].message);
			break;
		}
		var args = [value];
		if (functionMapper[i].arguments != null)
			args = args.concat(functionMapper[i].arguments);
		if (!ValidationMethods[funcName].apply(ValidationMethods, args)) {
			VALIDATION_MESSAGES.push(functionMapper[i].message);
			if (funcName == 'isNotEmpty' || funcName == 'isNotBlank')
				break;	//如果不满足NotEmpty和NotBlank条件，该组件的其他验证都不需要再处理
		}
	}
}

/**
 * 单个方法验证
 * @param validateFunc
 * @param message
 * @return
 */
function validateMethod(validateFunc, message) {
	if (!validateFunc())
		VALIDATION_MESSAGES.push(message);
}

/**
 * 显示错误消息
 * 如果有错误消息则返回false
 * 没有错误消息则返回true
 * @return
 */
function showValidationMessages() {
	if (VALIDATION_MESSAGES.length > 0) {
		var message = "";
		jQuery.each(VALIDATION_MESSAGES, function (i, n) {
			message += n + "<br/>";
		});
		VALIDATION_MESSAGES = [];
		aicommon.jsf.messagesMP.show(message);
		return false;
	}
	return true;
}

/**
 * 执行客户端验证
 * @param validateMethods
 * @return
 */
function invokeValidation(validateMethods) {
	for (var i = 0; i < validateMethods.length; i++) {
		validateMethods[i]();
	}
	return showValidationMessages();
}

/**
 * 添加验证方法
 * @param validateMethods
 * @param method
 * @param autoGen true 系统生成的验证方法， false 用户手动添加
 * @return
 */
function addValidateMethod(method, autoGen) {
	if (autoGen && window.inForm_AddValidateMethods)
		inForm_AddValidateMethods(method);
	else if (!autoGen && window.inForm_AddUserValidateMethods)
		inForm_AddUserValidateMethods(method);
}

/**
 * 根据预定义的验证方法生成并添加一个校验方法
 * functionMapper的定义如下
 * functionMapper = [
 * 		{
 * 			funcName : "isNotBlank",
 * 			message : "XXX字段不能为空"
 * 		},
 * 		{
 * 			funcName : "isInRange",
 * 			arguments : [10, 5],
 * 			message : "XXX字段必须是5~10之间"
 * 		}
 * ]
 * @param name
 * @param functionMapper
 * @return
 */
function createAndAddValidateMethod(name, functionMapper) {
	addValidateMethod (function () {
		validateInput(void(0), name, functionMapper);
	});
}


/**
 * 验证失败时添加错误消息
 * @param message
 * @return
 */
function addMessage(message) {
	VALIDATION_MESSAGES.push(message);
}

// ----------------------------------------------------------- 验证方法

ValidationMethods = {
	
	DIGIT_PATTERN : /^-?(?:(?:0)|(?:[1-9]\d*))(?:\.\d+)?$/,
	
	/**
	 * 验证是否是数值，对应javax.validation.constraints.Digits
	 * @param {String} value	待验证值
	 * @param {Number} integer	整数精度
	 * @param {Number} fraction	小数精度
	 */
	isDigit : function(value, integer, fraction) {
		if (!value) return true;
		if (this.DIGIT_PATTERN.test(value)) {
			var n = parseFloat(value);
			if (!isNaN(n)) {
				var s = (n + "").split('.');
				var result = s[0].length <= integer;
				if (result && s.length == 2 && s[1].length > fraction)
					result = false;
				return result;
			}
		}
		return false;
	},
	
	/**
	 * 验证小于等于，对应javax.validation.constraints.Max与javax.validation.constraints.DecimalMax
	 * @param {String} value	待验证值
	 * @param {Number} maxValue	最大值限制
	 */
	isLessOrEqual : function(value, maxValue) {
		if (!value) return true;
		return this.DIGIT_PATTERN.test(value) && parseFloat(value) <= maxValue; 
	},
	
	/**
	 * 验证大于等于，对应javax.validation.constraints.Min与javax.validation.constraints.DecimalMin
	 * @param {String} value	待验证值
	 * @param {Number} minValue	最小值限制
	 */
	isGreatOrEqual : function(value, minValue) {
		if (!value) return true;
		return this.DIGIT_PATTERN.test(value) && parseFloat(value) >= minValue;
	},
	
	/**
	 * 验证Email地址，对应org.hibernate.validator.constraints.Email
	 * 算法请参考org.hibernate.validator.constraints.impl.EmailValidator
	 * @param {String} value	待验证值
	 */
	isEmail : function(value) {
		if (!value) return true;
		var ATOM = "[a-z0-9!#$%&'*+/=?^_`{|}~-]";
		var DOMAIN = "(" + ATOM + "+(\\." + ATOM + "+)*";
		var IP_DOMAIN = "\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\]";
		
		var pattern = new RegExp("^" + ATOM + "+(\\." + ATOM + "+)*@"
					+ DOMAIN
					+ "|"
					+ IP_DOMAIN
					+ ")$", "i");
		return pattern.test(value);
	},
	
	/**
	 * 验证信用卡号，对应org.hibernate.validator.constraints.CreditCardNumber
	 * 算法请参考org.hibernate.validator.constraints.impl.CreditCardNumberValidator
	 * @param {String} value	待验证值
	 */
	isCreditCardNumber : function(value) {
		if (!value) return true;
		
		var chars = value.split('');
		
		var digits = [];
		for (var i = 0; i < chars.length; i++) {
			var n = parseInt(chars[i], 10);
			if (!isNaN(n)) {
				digits.push(chars[i].charCodeAt(0) - '0'.charCodeAt(0));
			}
		}
		
		var length = digits.length;
		var sum = 0;
		var even = false;
		for ( var index = length - 1; index >= 0; index-- ) {
			var digit = digits[ index ];
			if ( even ) {
				digit *= 2;
			}
			if ( digit > 9 ) {
				digit = Math.floor(digit / 10) + digit % 10;
			}
			sum += digit;
			even = !even;
		}
		return sum % 10 == 0;
	},
	
	/**
	 * 验证数值区间，对应org.hibernate.validator.constraints.Range
	 * @param {String} value	待验证值
	 * @param {Number} maxValue	最大限制值
	 * @param {Number} minValue	最小限制值
	 */
	isInRange : function(value, maxValue, minValue) {
		if (!value) return true;
		if (this.DIGIT_PATTERN.test(value)) {
			var n_value = parseFloat(value);
			if (!isNaN(n_value)) {
				return n_value <= maxValue && n_value >= minValue;	
			}
		}
		return false;
	},
	
	/**
	 * 验证不能是空白，对应org.hibernate.validator.constraints.NotBlank
	 * @param {String} value	待验证值
	 */
	isNotBlank : function(value) {
		return typeof value == "string" && jQuery.trim(value) !== "";
	},
	
	/**
	 * 验证不能是空字符串，对应org.hibernate.validator.constraints.NotEmpty
	 * @param {String} value
	 */
	isNotEmpty : function(value) {
		return (typeof value == "string" && value !== "") || (value instanceof Array && value.length != 0);
	},
	
	/**
	 * 验证字符串或数组长度，对应javax.validation.constraints.Size与org.hibernate.validator.constraints.Length
	 * @param {String} value		待验证值
	 * @param {Number} maxLength	最大长度值
	 * @param {Number} minLength	最小长度值
	 */
	isLengthInRange : function(value, maxLength, minLength) {
		if (!value) return true;
		return (typeof value == "string" || value instanceof Array) && value.length >= minLength && value.length <= maxLength;
	},
	
	/**
	 * 自定义验证Sample
	 * 对应com.ai.core.jsf.validation.constraints.CheckCase
	 * 验证字母的大小写
	 * @param {String} value	待验证字符串
	 * @param {String} caseMode	验证规则
	 */
	isCaseValid : function(value, caseMode) {
		if (!value) return true;
		if (caseMode == 'UPPER')
			return value == value.toUpperCase();
		else if (caseMode == 'LOWER')
			return value == value.toLowerCase();
		return false;
	},
	
	/**
	 * 对应com.ai.core.jsf.validation.constraints.Pattern
	 * 正则验证，程序中使用了eval，这是必要的，
	 * 否则无法在正则表达式上加g(全局)、i(大小写不敏感)、m(多行模式)属性。
	 * 一个有效的regex参数例子：/^\\d{1,6}$/gim
	 * @param {String} value	待验证字符串
	 * @param {String} regexp	字符串形式描述的正则表达式
	 */
	isPatternMatch : function(value, regex) {
		if (!value) return true;
		var pattern = eval(regex);	
		return pattern.test(value);
	},
	
	/**
	 * 验证给定时间是否在指定的时间区间内（包含左右时间点）
	 * @param {String}	value		待验证值
	 * @param {String}	maxValue	最大值（右值）
	 * @param {String}	minValue	最小值（左值）
	 * @param {String}	dateFormat	待验证值的格式
	 */
	isInDateRange : function (value, maxValue, minValue, dateFormat) {
		
		var DATE_PATTERN = /^\d{4}-\d{1,2}-\d{1,2}$/;
		var TIME_PATTERN = /^\d{1,2}:\d{1,2}:\d{1,2}$/;
		var DATE_TIME_PATTERN = /^\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}$/;
		var PATTERN_FORMAT = '';
		if (DATE_TIME_PATTERN.test(maxValue) && DATE_TIME_PATTERN.test(minValue))
			PATTERN_FORMAT = 'yyyy-M-d H:m:s';
		else if (TIME_PATTERN.test(maxValue) && TIME_PATTERN.test(minValue))
			PATTERN_FORMAT = 'H:m:s';
		else if (DATE_PATTERN.test(maxValue) && DATE_PATTERN.test(minValue))
			PATTERN_FORMAT = 'yyyy-M-d';
		else
			throw new Error('DateRange校验器min与max参数的格式错误');
		
		var minDate = parseDate(minValue, PATTERN_FORMAT);
		var maxDate = parseDate(maxValue, PATTERN_FORMAT);
		var compareDate = parseDate(value, dateFormat);
		
		return compareDate.getTime() >= minDate.getTime() && compareDate.getTime() <= maxDate.getTime();
	},
	
	/**
	 * 验证给定的手机号码是属于特定的运营商
	 * @param {String}	value		待验证值
	 * @param {String}	carrier		运营商, 中国移动(CMCC), 中国联通(CUCC), 中国电信(CTCC), 全部运营商(ALL)
	 */
	isMobilePhoneMatch : function (value, carriers) {
		if(value==""){
			return true
		}
		
		var PHONE_PATTERN =/^\d{11}$/;
		if(!PHONE_PATTERN.test(value)){
			return false;
		} 
		var PREFIX = value.substring(0, 3);
		
		var cuccFlag = false;
		var cmccFlag = false;
		var ctccFlag = false;
		var allFlag = false;
		
		for(var i=0;i<carriers.length;i++){
			var carrier = carriers[i];
			if(carrier == 'CUCC'){
				cuccFlag = (PREFIX=='130'||PREFIX=='131'||PREFIX=='132'||PREFIX=='155'||PREFIX=='156'||PREFIX=='186' || PREFIX=='185');
			}
			if(carrier == 'CMCC'){
				cmccFlag = (PREFIX=='134'||PREFIX=='135'||PREFIX=='136'||PREFIX=='137'||PREFIX=='138'||PREFIX=='139'||PREFIX=='150'||PREFIX=='151'||PREFIX=='152'||PREFIX=='157'||PREFIX=='158'||PREFIX=='159'||PREFIX=='188'||PREFIX=='182'||PREFIX=='187');
			}
			if(carrier == 'CTCC'){
				ctccFlag = (PREFIX=='133'||PREFIX=='153'||PREFIX=='189'||PREFIX=='180');
			}
			if(carrier == 'ALL'){
				allFlag = (PREFIX=='130'||PREFIX=='131'||PREFIX=='132'||PREFIX=='155'||PREFIX=='156'||PREFIX=='186' || PREFIX=='185'||PREFIX=='134'||PREFIX=='135'||PREFIX=='136'||PREFIX=='137'||PREFIX=='138'||PREFIX=='139'||PREFIX=='150'||PREFIX=='151'||PREFIX=='152'||PREFIX=='157'||PREFIX=='158'||PREFIX=='159'||PREFIX=='188'||PREFIX=='133'||PREFIX=='153'||PREFIX=='189'||PREFIX=='182'||PREFIX=='180'||PREFIX=='187');
			}
		}
		return cuccFlag||cmccFlag||ctccFlag||allFlag;
	}
}


